package andev.aandroidlib.util;

import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * Created by lzy1g on 2015/9/25.
 */
public class AHttp {
    final int ONSUCCESS = 1, ONFAILURE = 0;
    public Map<String, String> headers = null;
    public Map<String, String> params = null;
    Context context;
    URL url;
    HttpURLConnection conn;
    int connectTimeout = 15 * 1000;
    String requestMethod;
    String requestURL;
    HttpListener httpListener;
    String cookie;
    Handler handler;
    String paramsEncoding = "utf-8";

    public AHttp(Context context, String sURL, String method, Map<String, String> headers, Map<String, String> params, HttpListener l) {
        this.context = context;
        handler = new Handler(context.getMainLooper()) {
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                Bundle bundle = msg.getData();
                switch (msg.what) {
                    case ONSUCCESS:
                        httpListener.OnSuccess((byte[]) msg.obj);
                        break;
                    case ONFAILURE:
                        httpListener.OnFailure(bundle.getInt("responseCode"), (Map<String, List<String>>) msg.obj);
                        break;
                }
            }
        };
        requestMethod = method;
        requestURL = sURL;
        this.headers = headers;
        this.params = params;
        this.httpListener = l;
    }

    public void connect() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                setConn();
                try {
                    if (params != null) {
                        OutputStream connOutputStream = conn.getOutputStream();
                        connOutputStream.write(encodeParams());
                        connOutputStream.flush();
                        connOutputStream.close();
                    }

                    parseResult();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    private void parseResult() {
        try {
            int responseCode = conn.getResponseCode();
            if (responseCode == 200) {
                InputStream connInputStream = conn.getInputStream();
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                byte[] tp = new byte[4096];
                int realRead = 0;
                while ((realRead = connInputStream.read(tp)) != -1) {
                    baos.write(tp, 0, realRead);
                }
                connInputStream.close();

                Message msg = new Message();
                msg.what = ONSUCCESS;
                Bundle response = new Bundle();
                msg.obj = baos.toByteArray();
                response.putString("cookie", cookie);
                msg.setData(response);
                handler.sendMessage(msg);
                //httpListener.OnSuccess(baos.toByteArray(),cookie);
            } else {
                Message msg = new Message();
                msg.what = ONFAILURE;
                msg.obj = conn.getHeaderFields();
                Bundle response = new Bundle();
                response.putInt("responseCode", responseCode);
                msg.setData(response);
                handler.sendMessage(msg);
                //httpListener.OnFailure(responseCode,conn.getHeaderFields());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void setParamsEncoding(String paramsEncoding) {
        this.paramsEncoding = paramsEncoding;
    }

    private byte[] encodeParams() {
        StringBuilder encodedParams = new StringBuilder();

        try {
            Iterator var5 = params.entrySet().iterator();

            while (var5.hasNext()) {
                java.util.Map.Entry uee = (java.util.Map.Entry) var5.next();
                encodedParams.append(URLEncoder.encode((String) uee.getKey(), paramsEncoding));
                encodedParams.append('=');
                encodedParams.append(URLEncoder.encode((String) uee.getValue(), paramsEncoding));
                if (var5.hasNext())
                    encodedParams.append('&');
            }
            return encodedParams.toString().getBytes(paramsEncoding);
        } catch (UnsupportedEncodingException var6) {
            throw new RuntimeException("Encoding not supported: " + paramsEncoding, var6);
        }
    }

    private void setConn() {
        try {
            url = new URL(requestURL);
            conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod(requestMethod);
        } catch (Exception e) {
            e.printStackTrace();
        }
        conn.setConnectTimeout(connectTimeout);
        conn.setDoOutput(true);
        conn.setUseCaches(false);
        conn.setInstanceFollowRedirects(true);
        //conn.setRequestProperty("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
        //conn.setRequestProperty("Accept-Language", "zh-CN,zh;q=0.8");
        //conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.157 Safari/537.36");
        //conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        //conn.setRequestProperty("Connection", "keep-alive");
        if (conn != null && headers != null) {
            Iterator<String> iterator = headers.keySet().iterator();
            while (iterator.hasNext()) {
                String key = iterator.next();
                String value = headers.get(key);
                conn.setRequestProperty(key, value);
            }
        }
    }

    public interface HttpListener {
        void OnSuccess(byte[] bytes);

        void OnFailure(int code, Map<String, List<String>> responseHeaders);
    }
}
